package midoo.server.core;

import com.google.common.base.Strings;
import midoo.common.MServer;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by ajianzheng on 2015/4/11.
 *
 */

public class MServerBench implements MServer, MOverload, MMessageConsumer, MServerUserEvent {
    final private static String serverBenchVersion = "kiwi-1.0.0 ajian.zheng";

    private MServerBench() {
    }

    private static class SingletonHolder {
        static final MServerBench instance = new MServerBench();
    }

    public static MServerBench getInstance() {
        return SingletonHolder.instance;
    }

    ///
    private String serverName;
    private MServerBootstrap serverBootstrap = new MServerBootstrap();
    private MServerBenchControl serverBenchControl = new MServerBenchControl();

    private MWorker worker;

    public void setWorker(MWorker worker) {
        this.worker = worker;
    }

    public String getServerBenchVersion() {
        return serverBenchVersion;
    }

    @Override
    public int handleProcess(MMessage message) {
        return worker.handleProcess(message);
    }

    @Override
    public void handleOverload(KOverloadType type, Object object) {
        worker.handleOverload(type, object);
    }

    @Override
    public String handleUserEvent(String s) {
        return worker.handleUserEvent(s);
    }

    @Override
    public int start(String[] args) throws Exception {
        Options options = new Options();
        options.addOption("spring", true, "ServerBench config file path");

        CommandLineParser parser = new BasicParser();
        CommandLine cmd = parser.parse(options, args);

        String configFile = cmd.getOptionValue("spring");
        if (Strings.isNullOrEmpty(configFile)) {
            configFile = "beans.xml";
        }

        ///
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println(serverName + " shutdown...");
                MServerBench.getInstance().stop();
            }
        });

        ApplicationContext ctx = new ClassPathXmlApplicationContext(configFile);

        /// init executor
        MMessageExecutorConfig disruptorConfig = (MMessageExecutorConfig) ctx.getBean("executor");
        MMessageExecutor.getInstance().start(disruptorConfig);

        /// init bootstrap
        MServerBootstrapConfig serverConfig = (MServerBootstrapConfig) ctx.getBean("bootstrap");
        serverBootstrap.start(serverConfig);

        /// init control
        MServerBootstrapConfig controlConfig = (MServerBootstrapConfig) ctx.getBean("control");
        if (0 == controlConfig.getPort()) {
            controlConfig.setPort(52222);
        }
        serverBenchControl.start(controlConfig);

        /// init stat
        MChannelStatisticsConfig statisticsConfig = (MChannelStatisticsConfig) ctx.getBean("statistics");
        MChannelStatistics.getInstance().start(statisticsConfig);

        ///
        worker.start(args);

        serverName = serverConfig.getServerName();

        return 0;
    }

    @Override
    public void stop() {
        if (null != worker) worker.stop();
        if (null != serverBootstrap) serverBootstrap.stop();
        MMessageExecutor.getInstance().stop();
        MChannelStatistics.getInstance().stop();
    }
}
